﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Log = Logger.Debug;

namespace Xiaowei
{
    public class LockScreen
    {
        public delegate void LockScreenEventHandler(bool locked);
        public event LockScreenEventHandler Locked;
        public bool skipDetect = false;
        private bool? isLockScreen;

        public LockScreen()
        {
            Services.ServiceFactory.NativeMessageService.SystemResumed += (sender, e) =>
            {
                Task.Run(() =>
                {
                    //After resumed , lock screen app sometimes is still sleep, so the first lock detection ignore.
                    //after resumed , keep 4 secs for lockapp recovery from sleep
                    Task.Delay(4000);
                    skipDetect = false;
                });

            };

            Services.ServiceFactory.NativeMessageService.SystemSuspended += (sender, e) =>
            {
                //after suspending, ignore lock dectection
                skipDetect = true;
            };


        }

        private readonly object locker = new object();
        public bool IsLocked
        {
            get
            {
                if (isLockScreen.HasValue)
                {
                    return isLockScreen.Value;
                }
                else
                {
                    isLockScreen = IsLockScreen();
                    return isLockScreen.Value;
                }
            }
            set
            {
                if (isLockScreen != value)
                {
                    lock (locker)
                    {
                        Log.WriteLine($"LockScreen, IsLocked: {value}");
                        isLockScreen = value;
                        Locked?.Invoke(value);
                    }
                }
            }
        }

        public void Detect()
        {
            //After resumed , lock screen app sometimes is still sleep, so the first lock detection ignore.
            if (skipDetect)
            {
                Log.WriteLine("Lock dectect ignore");
                return;
            }
            Debug.WriteLine($"LockScreen.Detect, Enter:{IsLocked}");
            IsLocked = IsLockScreen();
            Debug.WriteLine($"LockScreen.Detect, Exit:{IsLocked}");
        }

        public bool IsLockScreen()
        {
            if(isLockScreenByLockApp() && isLockScreenByLogonUI())
            {
                return true;
            }
            return false;
        }

        private bool isLockScreenByLockApp()
        {
            var ps = Process.GetProcessesByName("LockApp");
            foreach (var p in ps)
            {
                //Log.WriteLine($"p:{p.ProcessName}, id:{p.Id}， responding:{p.Responding}");
                //Log.WriteLine($"WaitReason:{p.Threads[0].WaitReason}, ThreadState:{p.Threads[0].ThreadState}");

                if (p.Threads[0].WaitReason == ThreadWaitReason.UserRequest)
                {
                    Log.WriteLine($"IsLockApp: true");
                    return true;
                }
            }
            Log.WriteLine($"IsLockApp: false");
            return false;
        }

        private bool isLockScreenByLogonUI()
        {
            var ps = Process.GetProcessesByName("logonui");
            foreach (var p in ps)
            {
                //Log.WriteLine($"p:{p.ProcessName}, id:{p.Id}， responding:{p.Responding}");
                //Log.WriteLine($"WaitReason:{p.Threads[0].WaitReason}, ThreadState:{p.Threads[0].ThreadState}");

                if (p.Threads[0].WaitReason == ThreadWaitReason.UserRequest)
                {
                    Log.WriteLine($"IsLogonUI: true");
                    return true;
                }
            }
            Log.WriteLine($"IsLogonUI: false");
            return false;
        }
    }
}
